// tbitstr.cpp: A cursory test for the Bits class
// Simply compile along with your .cpp file.
// Author: Chuck Allison
#include <iostream>
#include <sstream>
#include <stdexcept>
#include "bits.h"
#include "test.h"

using namespace std;
//
//#ifdef _MSC_VER
//#pragma warning(disable: 4305)
//#endif

// Test program
int main() 
{	
   Bits b;
   // Test some exceptions
   try 
   {
      b[0];
      fail_("indexed empty bitstring");
   }
   catch (logic_error&) 
   {
      succeed_();
   }
   try 
   {
      b.toggle(0);
      fail_("toggle empty bitstring");
   }
   catch (logic_error&) 
   {
      succeed_();
   }
   try 
   {
      const Bits b2(b);
      b2[0];
      fail_("bad index in const bitstring");
   }
   catch (logic_error&) 
   {
      succeed_();
   }
   test_(b.size() == 0);
   test_(b.count() == 0);
   test_(!b.any());
   
   // Validate construction and to_string()
   Bits b2(5);
   test_(b2.size() == 5);
   for (size_t i = 0; i < 5; ++i) 
   {
	 test_(!b2[i]);
   }
   test_(tostring(b2) == "00000");

   // Test copy, assign, equality, and from_string
   Bits b3(b2);
   test_(b2 == b3);
   test_(b != b2);
   test_(!b3[2]);
   b3[2] = 1;
   test_(b3[2]);
   test_(b2 != b3);
   test_(tostring(b2) == "00000");
   b = b2;
   test_(tostring(b) == "00000");

   //// Test bit ops
   Bits x("011010110");
   test_(x.count() == 5);
   test_(x.any());
   test_(tostring(x << 6) == "110000000");
   test_(tostring(x >> 6) == "000000011");
   test_(tostring(x <<= 3) == "010110000");
   test_(tostring(x >>= 3) == "000010110");
   Bits y(~x);
   x.toggle();
   test_(x == y);
   test_(tostring(x) == "111101001");

   b = Bits();
   test_(!b.any());
   b += 1;
   b += 0;
   b += 2;
   test_(tostring(b) == "101");
   test_(b.any());

   b2 = Bits("10101011");
   test_(b2.count() == 5);
   b2.toggle();
   test_(tostring(b2) == "01010100");
   b2.erase(3);
   test_(tostring(b2) == "0100100");
   b2.erase(b2.size()-1);
   test_(tostring(b2) == "010010");
   b2.erase(1,4);
   test_(tostring(b2) == "00");
   b2.insert(1,1);
   test_(tostring(b2) == "010");
   b2.insert(1,0);
   test_(tostring(b2) == "0010");
   b2 += b;
   test_(tostring(b2) == "0010101");
   b2.insert(3, b);
   test_(tostring(b2) == "0011010101");

   ostringstream os;
   os << "101" << 'a' << "0101";
   istringstream is(os.str());
   b3 = Bits();
   is >> b3;
   test_(tostring(b3) == "101");
   is.get();
   is >> b3;
   test_(tostring(b3) == "0101");
   os.str("");
   os << 'a';
   istringstream is2(os.str());
   is2 >> b3;
   test_(!is2);
   test_(tostring(b3) == "0101");
   
   vector<unsigned char> bytes(b2.bytes());
   Bits b4(bytes);
   string b4str(tostring(b4));
   b4str.resize(b2.size());
   string s1 = tostring (b2);
   test_(tostring(b2) == b4str);
   test_(tostring(b2.slice(2,5)) == "11010");

   Bits b5("11111111111111111111111111000000000000000000000000000011");
   size_t n = b4.size();
   b4.insert(3,b5);
   test_(n + b5.size() == b4.size());
   b4.erase(3, b5.size());
   b4.compress();

   Bits b6("11011");
   Bits b7("11010");
   test_(b6 > b7);
   test_(b7 < b6);
   test_(b6 >= b7);
   test_(b6 >= b6);
   test_(b7 <= b6);
   test_(b7 <= b7);
   do_report();
	cin.get();
}

